/*
 * Number of Times 
 */

#ifndef USER_PASSWORD_DYNAMIC_NOTS_H
#define USER_PASSWORD_DYNAMIC_NOTS_H

#ifndef USER_PASSWORD_DYNAMIC_H
#error "include user_password_dynamic.h instead!"
#endif

#ifdef GKT_CONFIG_USER_PASSWORD_DYNAMIC_NOTS_ENABLE
#define USER_DYNPWD_NOTS_ENABLE	\
	GKT_CONFIG_USER_PASSWORD_DYNAMIC_NOTS_ENABLE
#else
#define USER_DYNPWD_NOTS_ENABLE	0
#endif

#define USER_DYNPWD_NOTS_DIGITS_SIZE	13

#define USER_DYNPWD_NOTS_TIMES_MAX	10

#define USER_DYNPWD_NOTS_MINUTE_STEP	10
#define USER_DYNPWD_NOTS_MINUTE_STEPS_MAX	\
	(GKT_DT_MINUTE_SECONDS / USER_DYNPWD_NOTS_MINUTE_STEP)

#define USER_DYNPWD_NOTS_YEAR_OFFSET_MAX	15
#define USER_DYNPWD_NOTS_TAG_VALUE	0x0A	/* 0b1010 */

/* NOTS: number of times */
#define USER_DYNPWD_NOTS_TIMES_BITS	4
#define USER_DYNPWD_NOTS_MINUTE_STEPS_BITS	3
#define USER_DYNPWD_NOTS_HOUR_BITS	5
#define USER_DYNPWD_NOTS_DAY_BITS	5
#define USER_DYNPWD_NOTS_MONTH_BITS	4
#define USER_DYNPWD_NOTS_YEAR_OFFSET_BITS	4
#define USER_DYNPWD_NOTS_TAG_BITS	4

#define USER_DYNPWD_NOTS_FIELD_MASK(FIELD)	\
	((1U << USER_DYNPWD_NOTS_##FIELD##_BITS) - 1)

#define USER_DYNPWD_NOTS_TIMES_SHIFT	\
	(USER_DYNPWD_GENERAL_SHIFT + USER_DYNPWD_GENERAL_BITS)
#define USER_DYNPWD_NOTS_MINUTE_STEPS_SHIFT	\
	(USER_DYNPWD_NOTS_TIMES_SHIFT + USER_DYNPWD_NOTS_TIMES_BITS)
#define USER_DYNPWD_NOTS_HOUR_SHIFT	\
	(USER_DYNPWD_NOTS_MINUTE_STEPS_SHIFT + USER_DYNPWD_NOTS_MINUTE_STEPS_BITS)
#define USER_DYNPWD_NOTS_DAY_SHIFT	\
	(USER_DYNPWD_NOTS_HOUR_SHIFT + USER_DYNPWD_NOTS_HOUR_BITS)
#define USER_DYNPWD_NOTS_MONTH_SHIFT	\
	(USER_DYNPWD_NOTS_DAY_SHIFT + USER_DYNPWD_NOTS_DAY_BITS)
#define USER_DYNPWD_NOTS_YEAR_OFFSET_SHIFT	\
	(USER_DYNPWD_NOTS_MONTH_SHIFT + USER_DYNPWD_NOTS_MONTH_BITS)
#define USER_DYNPWD_NOTS_TAG_SHIFT	\
	(USER_DYNPWD_NOTS_YEAR_OFFSET_SHIFT + USER_DYNPWD_NOTS_YEAR_OFFSET_BITS)

#define USER_DYNPWD_NOTS_TOTAL_BITS	\
	(USER_DYNPWD_NOTS_TAG_SHIFT + USER_DYNPWD_NOTS_TAG_BITS)
#define USER_DYNPWD_NOTS_TOTAL_UNITS	\
	((USER_DYNPWD_NOTS_TOTAL_BITS + 3) >> 2)
	
#define USER_DYNPWD_NOTS_FIELD(value, FIELD)	\
	(((value) >> USER_DYNPWD_NOTS_##FIELD##_SHIFT) \
		& USER_DYNPWD_NOTS_FIELD_MASK(FIELD))

typedef struct _user_dynpwd_nots_data {
	uint32_t	total_times;
	uint32_t	dtu;
} user_dynpwd_nots_data_s;

typedef struct _user_dynpwd_nots_item_data {
	uint32_t	dtu;
	uint16_t	total_times;
	uint16_t	left_times_bits;
} user_dynpwd_nots_item_data_s;

#if USER_DYNPWD_NOTS_ENABLE
int user_dynpwd_NOTS_retrieve(user_dynpwd_data_s *data,
				uint32_t *values);
int user_dynpwd_NOTS_verify(user_dynpwd_data_s *data,
				uint32_t admin_item_index);
#else
#define user_dynpwd_NOTS_retrieve	NULL
#define user_dynpwd_NOTS_verify	NULL
#endif

#endif

